package org.ourgrid.acceptance.broker;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.ourgrid.acceptance.util.broker.Req_301_Util;
import org.ourgrid.acceptance.util.broker.Req_302_Util;
import org.ourgrid.acceptance.util.broker.Req_304_Util;
import org.ourgrid.acceptance.util.broker.Req_309_Util;
import org.ourgrid.acceptance.util.broker.Req_311_Util;
import org.ourgrid.acceptance.util.broker.Req_312_Util;
import org.ourgrid.acceptance.util.broker.Req_327_Util;
import org.ourgrid.acceptance.util.broker.Req_328_Util;
import org.ourgrid.acceptance.util.broker.Req_329_Util;
import org.ourgrid.acceptance.util.broker.TestJob;
import org.ourgrid.broker.BrokerComponent;
import org.ourgrid.broker.BrokerConstants;
import org.ourgrid.broker.controller.LocalWorkerProviderNotificationController;
import org.ourgrid.common.interfaces.LocalWorkerProvider;
import org.ourgrid.common.interfaces.to.GridProcessHandle;
import org.ourgrid.common.spec.peer.PeerSpec;
import org.ourgrid.common.spec.worker.WorkerSpec;
import org.ourgrid.peer.PeerConstants;
import org.ourgrid.reqtrace.ReqTest;

import br.edu.ufcg.lsd.commune.functionaltests.util.TestStub;
import br.edu.ufcg.lsd.commune.identification.DeploymentID;
import br.edu.ufcg.lsd.commune.test.AcceptanceTestUtil;

@ReqTest(reqs="REQ309")
public class Req_309_Test extends BrokerAcceptanceTestCase {

	private Req_301_Util req_301_Util = new Req_301_Util(getComponentContext());
	private Req_302_Util req_302_Util = new Req_302_Util(getComponentContext());
	private Req_304_Util req_304_Util = new Req_304_Util(getComponentContext());
	private Req_309_Util req_309_Util = new Req_309_Util(getComponentContext());
	private Req_311_Util req_311_Util = new Req_311_Util(getComponentContext());
	private Req_312_Util req_312_Util = new Req_312_Util(getComponentContext());
	private Req_327_Util req_327_Util = new Req_327_Util(getComponentContext());
	private Req_328_Util req_328_Util = new Req_328_Util(getComponentContext());
	private Req_329_Util req_329_Util = new Req_329_Util(getComponentContext());

	/**
	 * This test contains the following steps:
	 * 
     * Create a Broker with the public key property set to "publicKey1";
     * 
     * Call setPeers with an empty peers list;
     * 
     * Verify if the following error message was logged:
     *   1. BrokerComponent is not started.
	 * 
	 */
	@ReqTest(test="AT-309.1", reqs="REQ309")
	@Test public void test_at_309_1_SetPeersWithoutBrokerStart() throws Exception {
		BrokerComponent broker = req_301_Util.createBrokerComponent();
		req_309_Util.setPeers(false, broker);
	}
	
	/**
	 * This test contains the following steps:
	 * 
     * Create a Broker with the public key property set to "publicKey1";
     * 
     * Call setPeers giving a list containing one peer;
     * 
     * Verify if the following error message was logged:
     *   1. BrokerComponent is not started.
     * Verify if the Control Operation Result contains an exception with the message above.
	 */
	@ReqTest(test="AT-309.2", reqs="REQ309")
	@Test public void test_at_309_2_SetOnePeerWithoutBrokerStart() throws Exception {
		BrokerComponent broker = req_301_Util.createBrokerComponent();
		req_309_Util.setPeers(false, "test", "servertest", "publicKey1", broker);
	}
	
	/**
	 *  This test contains the following steps:
	 *  *
     * Create a Broker with the public key property set to "publicKey1" and start the Broker;
     * 
     * Call setPeers giving a list containing one peer with the following attributes:
     *     o username = test
     *     o servername = servertest
     *     
     * Verify if the operation returned an empty Control Operation Result;
     * 
     * Get(lookup) the remote object "PEER_MONITOR_OBJECT_NAME" and verify if its type is:
     *     o org.ourgrid.jic.EventProcessor.FailureInterestedEventProcessor
     *     
     * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer added.
	 */
	@ReqTest(test="AT-309.3", reqs="REQ309")
	@Test public void test_at_309_3_StartBrokerAndSetOnePeer() throws Exception {
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		assertTrue(isBound(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME, LocalWorkerProviderNotificationController.class));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	/**
	 * Create a Broker with the public key property set to "publicKey1"
     * Start the Broker with the correct public key;
     * Add a job with the attributes: label: "Test Job" and one Task with remote attribute "echo Hello World"
     * Add another job with the attributes: label: "Test Job 2" and one Task with remote attribute "echo Hello World again"
     * Call setPeers giving a list containing one peer with the following attributes:
     *     o username = test
     *     o servername = servertest
     * Verify if the operation returned an empty Control Operation Result;
     * Get(lookup) the remote object "PEER_MONITOR_OBJECT_NAME" and verify if its type is:
     *     o org.ourgrid.jic.EventProcessor.FailureInterestedEventProcessor
     * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer added.
	 */
	@ReqTest(test="AT-309.4", reqs="REQ309")
	@Test public void test_at_309_4_StartBrokerAddJobsAndSetPeers() throws Exception {
		BrokerComponent broker = req_302_Util.startBroker();
		req_304_Util.addJob(true, 1, broker, "echo Hello World", "Test Job");
		req_304_Util.addJob(true, 2, broker, "echo Hello World 2", "Test Job 2");
		PeerSpec peer = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		assertTrue(isBound(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME, LocalWorkerProviderNotificationController.class));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}

	/**
	 * Create a Broker with the public key property set to "publicKey1" and start the Broker;
	 * Call setPeers giving a list containing one peer with the following attributes:
	 *       username = test
	 *       servername = servertest
	 * Verify if the operation returned an empty Control Operation Result;
	 * Get(lookup) the remote object "PEER_MONITOR_OBJECT_NAME" and verify if its type is:
	 *       org.ourgrid.jic.EventProcessor.FailureInterestedEventProcessor
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer added.
	 * Call again setPeers giving a list containing two peer with the following attributes:
	 *       First peer = username = test2 and servername = servertest2
	 *       Second peer = username = test3 and servername = servertest3
	 * Verify if the operation returned an empty Control Operation Result;
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest2
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest3
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was unregistered like an interested by the peer with servername = servertest
	 *
	 */
	@ReqTest(test="AT-309.5", reqs="REQ309")
	@Test public void test_at_309_5_SetNewPeers() throws Exception {
		BrokerComponent broker = req_302_Util.startBroker();
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer1 = req_309_Util.createPeerSpec("test", "servertest");
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test3", "servertest3");
		peers.add(peer1);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey1");
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey3");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(isBound(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME, LocalWorkerProviderNotificationController.class));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer1, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		
		peers.remove(peer1);
		publicKeys.remove("publicKey1");
		
		peers.add(peer2);
		peers.add(peer3);
	
		req_309_Util.setPeers(true, peers, publicKeys, broker);

		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey3", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertFalse(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer1, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	
	/**
	* Create a Broker with the public key property set to "publicKey1" and start the Broker;
    * Call setPeers giving a list containing one peer with the following attributes:
          o username = test
          o servername = servertest
    * Add a job with the attributes: label: "Test Job" and one Task with remote attribute 
    * 	"echo Hello World"
    * Add a job with the attributes: label: "Test Job 2" and one Task with remote attribute
    * 	"echo Hello World2"
    * Call setPeers giving a list containing one peer with the following attributes:
          o username = test2
          o servername = servertest2
    * Verify if the operation returned an empty Control Operation Result;
    * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like 
    * 	an interested by the peer added.
    * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was unregistered like 
    * 	an interested by the peer with servername = servertest

	 * @throws Exception
	 */
	@ReqTest(test="AT-309.6", reqs="REQ309")
	@Test public void test_at_309_6_SetANewPeer() throws Exception{
		BrokerComponent broker = req_302_Util.startBroker();
		
		//create and set the first peer
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		//create and add the first job
		req_304_Util.addJob(true, 1, broker, "Test Job", "echo Hello World");
		//create and add the second job
		req_304_Util.addJob(true, 2, broker, "Test Job 2", "echo Hello World 2"); 
		//create and set the second peer
		PeerSpec peer2 = req_309_Util.setPeers("test2", "servertest2", "publicKey2", broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertFalse(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer1, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	/**
	* Create a Broker with the public key property set to "publicKey1" and start the Broker;
    * Call setPeers giving a list containing one peer with the following attributes:
          o username = test
          o servername = servertest
    * Call doNotifyRecovery passing a peer with the attributes above on the parameter;
    * Verify if the following debug message was logged:
         1. Peer with object id: [X] is UP. Where X is the objectID generated.
    * Call again setPeers giving a list containing one peer with the following attributes:
          o First peer = username = test2 and servername = servertest2
          o Second peer = username = test3 and servername = servertest3
    * Verify if the operation returned an empty Control Operation Result;
    * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest2
    * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest3
    * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was unregistered like an interested by the peer with servername = servertest

	 * @throws Exception
	 */
	@ReqTest(test="AT-309.7", reqs="REQ309")
	@Test public void test_at_309_7_SetAPeerUp() throws Exception {
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		DeploymentID deploymentID = req_328_Util.createPeerDeploymentID("publicKey1", peer1);
		req_327_Util.notifyPeerRecovery(peer1, deploymentID, broker);
		
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test3", "servertest3");
		
		peers.add(peer2);
		peers.add(peer3);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey3");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey3", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertFalse(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer1, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	/**
	 * Create a Broker with the public key property set to "publicKey1" and start the Broker;
	 * Call setPeers giving a list containing one peer with the following attributes:
	 *        o username = test
	 *        o servername = servertest
	 * Add a job with the attributes: label: "Test Job" and one Task with remote attribute "echo Hello World"
	 * Call doNotifyRecovery passing a peer with the attributes above on the parameter;
	 * Verify if the following debug message was logged:
     *    1. Peer with object id: [X] is UP. Where X is the objectID generated.
	 * Call again setPeers giving a list containing two peer with the following attributes:
	 *         o First peer = username = test2 and servername = servertest2
	 *         o Second peer = username = test3 and servername = servertest3
	 * Verify if the operation returned an empty Control Operation Result;
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest2
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest3
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was unregistered like an interested by the peer with servername = servertest
	 *
	 */
	@ReqTest(test="AT-309.8", reqs="REQ309")
	@Test public void test_at_309_8_AddJobAndSetAUpPeer() throws Exception {
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		DeploymentID deploymentID = req_328_Util.createPeerDeploymentID("publicKey1", peer1);
		req_304_Util.addJob(true, 1, broker, "Test Job", "echo Hello World");
		req_327_Util.notifyPeerRecovery(peer1, deploymentID, broker);
		
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test3", "servertest3");
		
		peers.add(peer2);
		peers.add(peer3);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey3");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey3", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertFalse(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer1, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	/**
	 * Create a Broker with the public key property set to "publicKey1" and start the Broker;
	 * Call setPeers giving a list containing one peer with the following attributes: * username = test * servername = servertest
	 * Call doNotifyRecovery passing a peer with the attributes above on the parameter;
	 * Verify if the following debug message was logged:
	 *         Peer with object id: [X] is UP. Where X is the objectID generated.
	 * Do login with the public key property set to "publicKey1"in the worker provider.
	 * Call again setPeers giving a list containing one peer with the following attributes:
	 *         First peer = username = test2 and servername = servertest2
	 *         Second peer = username = test3 and servername = servertest3
	 * Verify if the operation returned an empty Control Operation Result;
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest2
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest3
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was unregistered like an interested by the peer with servername = servertest
	 *
	 * @throws Exception
	 */
	@ReqTest(test="AT-309.9", reqs="REQ309")
	@Test public void test_at_309_9_AddPeerToBrokerWithALoggedPeer() throws Exception {
		//creates and starts
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		DeploymentID deploymentID = req_328_Util.createPeerDeploymentID("publicKey1", peer1);
		TestStub testStub = req_327_Util.notifyPeerRecovery(peer1, deploymentID, broker);
		req_311_Util.verifyLogin(broker, "publicKey1", false, false, null, testStub);
		
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test3", "servertest3");
		peers.add(peer2);
		peers.add(peer3);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey3");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey3", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertFalse(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer1, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	/**
	 * Create a Broker with the public key property set to "publicKey1" and start the Broker;
	 * Call setPeers giving a list containing one peer with the following attributes:
	 *       First peer = username = test and servername = servertest
	 * Call doNotifyRecovery passing a peer with username = test on the parameter;
	 * Verify if the following debug message was logged:
	 *       Peer with object id: [X] is UP. Where X is the objectID generated.
	 * Do login with the public key property set to "publicKey1"in the worker provider.
	 * Add a job with the attributes: label: "Test Job" and one Task with remote attribute "echo Hello World"
	 * Verify if the operation result contains a jobID with value 1.
	 * Add a job with the attributes: label: "Test Job 2" and one Task with remote attribute "echo Hello World 2"
	 * Verify if the operation result contains a jobID with value 2.
	 * Call again setPeers giving a list containing one peer with the following attributes:
	 *       First peer = username = test2 and servername = servertest2
	 *       Second peer = username = test and servername = servertest
	 * Verify if the operation returned an empty Control Operation Result;
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest2
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest
	 *
	 * @throws Exception
	 */
	@ReqTest(test="AT-309.10", reqs="REQ309")
	@Test public void test_at_309_10_AddPeerWithJobsAndLoggesPeer() throws Exception {
		//creates and starts
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		DeploymentID deploymentID = req_328_Util.createPeerDeploymentID("publicKey1", peer1);
		
		List<LocalWorkerProvider> peerStubs = new ArrayList<LocalWorkerProvider>();		
		TestStub peerTestStub = req_327_Util.notifyPeerRecovery(peer1, deploymentID, broker);
		peerStubs.add((LocalWorkerProvider) peerTestStub.getObject());

		req_311_Util.verifyLogin(broker, "publicKey1", false, false, null, peerTestStub);

		//adds and verifies
		req_304_Util.addJob(true, 1, broker, "echo Hello World", "Test Job", peerStubs);
		req_304_Util.addJob(true, 2, broker, "echo Hello World 2", "Test Job 2", peerStubs);
		
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test", "servertest");
		peers.add(peer2);
		peers.add(peer3);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
	}
	
	/**
	 * Create and start the Broker with the correct public key;
     * Call setPeers giving a list containing one peer with the following attributes:
     *     o First peer = username = test and servername = servertest
     * Call doNotifyRecovery passing a peer with username = test on the parameter;
     * Verify if the following debug message was logged:
     *     o Peer with object id: [X] is UP. Where X is the objectID generated.
     * Do login with the public key property set to "publicKey1"in the worker provider.
     * Add a job with the attributes: label: "Test Job" and one Task with remote attribute "echo Hello World"
     * Verify if the operation result contains a jobID with value 1.
     * Add a job with the attributes: label: "Test Job 2" and one Task with remote attribute "echo Hello World 2"
     * Verify if the operation result contains a jobID with value 2.
     * Call hereIsWorker giving a worker with public key "workerPublicKey" and the request ID generated.
     * Call again setPeers giving a list containing one peer with the following attributes:
     *     o First peer = username = test2 and servername = servertest2
     *     o Second peer = username = test and servername = servertest
     * Verify if the operation returned an empty Control Operation Result;
     * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with 
     * servername = servertest2
     * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with 
     * servername = servertest
     * Add a job with the attributes: label: "Test Job 3" and one Task with remote attribute "echo Hello World 3"
     * Verify if the operation result contains a jobID with value 3.
     * Call doNotifyRecovery passing a peer with username = test on the parameter;
     * Call hereIsWorker giving a worker with public key "workerPublicKey" and the request ID 
     * generated by the job 3 from the peer with username = test;
     * Verify if the following debug message was logged:
     *     o The broker is not logged in the peer with public key [publicKey1]. 
     *     This worker with public key [workerPublicKey] delivery was ignored.
	 *
	 * @throws Exception
	 */
	@ReqTest(test="AT-309.11", reqs="REQ309")
	@Test public void test_at_309_11_AddPeerInABrokerWithWorkers() throws Exception {
		//creates and starts
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		DeploymentID deploymentID1 = req_328_Util.createPeerDeploymentID("publicKey1", peer1);
		
		List<LocalWorkerProvider> peerStubs = new ArrayList<LocalWorkerProvider>();		
		TestStub testStub = req_327_Util.notifyPeerRecovery(peer1, deploymentID1, broker);
		peerStubs.add((LocalWorkerProvider) testStub.getObject());
		
		req_311_Util.verifyLogin(broker, "publicKey1", false, false, null, testStub);

		//adds and verifies
		req_304_Util.addJob(true, 1, broker, "echo Hello World", "Test Job", peerStubs);
		TestJob jobStub = req_304_Util.addJob(true, 2, broker, "echo Hello World 2", "Test Job 2", peerStubs);
		
		//receive workers
		Map<String, String> attributes = new HashMap<String, String>();
		attributes.put(WorkerSpec.ATT_SERVERNAME, "xmpp.ourgrid.org");
		attributes.put(WorkerSpec.ATT_USERNAME, "username");
		req_312_Util.receiveWorker(broker, "workerPublicKey", true, true, true, true, new WorkerSpec(attributes), "publicKey1",
				testStub, jobStub);
		
		
		//set peers again
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test", "servertest");
		peers.add(peer2);
		peers.add(peer3);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey1");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey1", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		
		//add another job
		req_304_Util.addJob(true, 3, broker, "echo Hello World 3", "Test Job 3");
		
		DeploymentID deploymentID3 = req_328_Util.createPeerDeploymentID("publicKey1", peer3);
		TestStub peerTestStub = req_327_Util.notifyPeerRecovery(peer3, deploymentID3, broker);
		
		//receive workers again
		req_312_Util.receiveWorker(broker, "workerPublicKey", true, false, true, true, new WorkerSpec(attributes), "publicKey1", 
				peerTestStub, jobStub);
	}
	
	/**
	 * Create and start the Broker with the correct public key;
	 * Call setPeers giving a list containing one peer with the following attributes:
	 *        First peer = username = test and servername = servertest
	 * Call doNotifyRecovery passing a peer with username = test on the parameter;
	 * Verify if the following debug message was logged:
	 *         Peer with object id: [X] is UP. Where X is the objectID generated.
	 * Do login with the public key property set to "publicKey1"in the worker provider.
	 * Add a job with the attributes: label: "Test Job" and one Task with remote attribute "echo Hello World"
	 * Verify if the operation result contains a jobID with value 1.
	 * Add a job with the attributes: label: "Test Job 2" and one Task with remote attribute "echo Hello World 2"
	 * Verify if the operation result contains a jobID with value 2.
	 * Call hereIsWorker giving a worker with public key "workerPublicKey" and the request ID generated.
	 * Call schedule with the correct public key;
	 * Verify if the worker's startWork message was called;
	 * Call again setPeers giving a list containing one peer with the following attributes:
	 *         First peer = username = test2 and servername = servertest2
	 *         Second peer = username = test and servername = servertest
	 * Verify if the operation returned an empty Control Operation Result;
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest2;
	 * Verify if the remote object "PEER_MONITOR_OBJECT_NAME" was registered like an interested by the peer with servername = servertest;
	 * Call hereIsWorker giving a worker with public key "workerPublicKey" and the request ID generated from peer with username = test;
	 * Verify if the following warnmessage was logged:
	 *         The peer with public key [publicKey1], which is down, delivered a worker with public key: [workerPublicKey].
	 *
	 */
	@ReqTest(test="AT-309.12", reqs="REQ309")
	@Test public void test_at_309_12_AddPeersToBrokerWithScheduledWorkers() throws Exception {
		//creates and starts
		BrokerComponent broker = req_302_Util.startBroker();
		PeerSpec peer1 = req_309_Util.setPeers("test", "servertest", "publicKey1", broker);
		DeploymentID deploymentID1 = req_328_Util.createPeerDeploymentID("publicKey1", peer1);
		
		List<LocalWorkerProvider> peerStubs = new ArrayList<LocalWorkerProvider>();		
		TestStub peerTestStub = req_327_Util.notifyPeerRecovery(peer1, deploymentID1, broker);
		peerStubs.add((LocalWorkerProvider) peerTestStub.getObject());
		
		req_311_Util.verifyLogin(broker, "publicKey1", false, false, null, peerTestStub);

		//adds and verifies
		TestJob jobStub = req_304_Util.addJob(true, 1, broker, "echo Hello World", "Test Job", peerStubs);
		req_304_Util.addJob(true, 2, broker, "echo Hello World 2", "Test Job 2", peerStubs);
		
		//hereIsWorker call
		List<TestStub> testStubs = new ArrayList<TestStub>();
		Map<String, String> attributes = new HashMap<String, String>();
		attributes.put(WorkerSpec.ATT_SERVERNAME, "xmpp.ourgrid.org");
		attributes.put(WorkerSpec.ATT_USERNAME, "username");
		TestStub workerTestStub  = req_312_Util.receiveWorker(broker, "workerPublicKey", true, true, true, true, new WorkerSpec(attributes), 
				"publicKey1", peerTestStub, jobStub);
		testStubs.add(workerTestStub);
		
		//do Schedule
		req_329_Util.doSchedule(broker, testStubs, peerTestStub, jobStub, new GridProcessHandle(1, 1, 1));
		
		//set peers again
		List<PeerSpec> peers = new ArrayList<PeerSpec>();
		PeerSpec peer2 = req_309_Util.createPeerSpec("test2", "servertest2");
		PeerSpec peer3 = req_309_Util.createPeerSpec("test", "servertest");
		peers.add(peer2);
		peers.add(peer3);
		
		List<String> publicKeys = new ArrayList<String>();
		publicKeys.add("publicKey2");
		publicKeys.add("publicKey");
		
		req_309_Util.setPeers(true, peers, publicKeys, broker);
		
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer2, "publicKey2", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));
		assertTrue(AcceptanceTestUtil.isInterested(broker, req_309_Util.createServiceID(peer3, "publicKey", PeerConstants.LOCAL_ACCESS_OBJECT_NAME), 
				getBoundDeploymentID(broker, BrokerConstants.PEER_MONITOR_OBJECT_NAME)));

		req_312_Util.receiveWorker(broker, "workerPublicKey", true, false, false, true, new WorkerSpec(attributes), "publicKey", 
				peerTestStub, jobStub);
	}
}
